//
// Created on 2023/6/7.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef AVCODEC_CALLBACK_NAPI_H_
#define AVCODEC_CALLBACK_NAPI_H_
#include "avcodec_video_encoder_demo.h"
#include "video_encoder.h"
#include "avcodec_napi_utils.h"
#include <js_native_api_types.h>
#include <stdlib.h>
#include <sys/resource.h>

namespace OHOS {
namespace Media {
struct BufferInfo{
    uint8_t* data = nullptr;
    int32_t size = -1;
    int32_t pts = -1;
    int32_t offset = -1;
    uint32_t flags = 0;
    ~BufferInfo(){
        data = nullptr;
    }
};
struct ErrorCodeInfo{
    int32_t errorCode = 0;
};
class AvCodecCallbackNapi:public AVCodecCallback {
public:
    ~AvCodecCallbackNapi();
    void setOutputBufferAvailableCb(napi_env env,napi_ref callback);
    void setInputBufferAvailableCb(napi_env env,napi_ref callback);
    void setOnErrorCb(napi_env env,napi_ref callback);
    void setOnOutputFormatChangeCb(napi_env env,napi_ref callback);
    void OnCodecError(int32_t errorCode);
    void OnCodecErrorAsync(ErrorCodeInfo info) const;
    void OnOutputFormatChanged(AvFormat* format);
    void OnOutputFormatChangedAsync(AvFormat &format) const;
    void OnInputBufferAvailable(uint8_t* data, int32_t size);
    void OnInputBufferAvailableAsync(BufferInfo &info) const;
    void OnOutputBufferAvailable(unsigned char* data,int32_t size,int32_t pts,uint32_t flags);
    void OnOutputBufferAvailableAsync(const BufferInfo &info) const;
    static void outputTs(napi_env env, napi_value callbackTs, void * /*context*/, void *data);
private:
    napi_env onOutputBufferAvailableCb_env = nullptr;
    napi_env onErrorCb_env = nullptr;
    napi_env onOutputFormatChangeCb_env = nullptr;
    napi_env onInputBufferAvailableCb_env = nullptr;
    napi_ref onOutputBufferAvailableCb = nullptr;
    napi_ref onErrorCb = nullptr;
    napi_ref onOutputFormatChangeCb = nullptr;
    napi_ref onInputBufferAvailableCb = nullptr;
    uv_loop_s* onOutputBufferAvailableCbLoop = nullptr;
    uv_loop_s* onErrorCbLoop = nullptr;
    uv_loop_s* onOutputFormatChangeCbLoop = nullptr;
    uv_loop_s* onInputBufferAvailableCbLoop = nullptr;
    FILE* codec_fp = nullptr;
    napi_threadsafe_function mOutputThreadSafeFunc = nullptr;
};
struct AvFormatCallbackInfo{
    AvFormat info_;
    const AvCodecCallbackNapi* callback_napi_;
    AvFormatCallbackInfo(AvFormat info,const AvCodecCallbackNapi* callback_napi):info_(info),callback_napi_(callback_napi){}
    ~AvFormatCallbackInfo(){
        callback_napi_ = nullptr;
    }
};

struct BufferCallbackInfo{
    BufferInfo info_;
    const AvCodecCallbackNapi* callback_napi_;
    BufferCallbackInfo(BufferInfo info,const AvCodecCallbackNapi* callback_napi):info_(info),callback_napi_(callback_napi){}
    ~BufferCallbackInfo(){
        callback_napi_ = nullptr;
    }
};

struct ErrorCodeCallbackInfo{
    ErrorCodeInfo info_;
    const AvCodecCallbackNapi* callback_napi_;
    ErrorCodeCallbackInfo(ErrorCodeInfo info,const AvCodecCallbackNapi* callback_napi):info_(info),callback_napi_(callback_napi){}
    ~ErrorCodeCallbackInfo(){
        callback_napi_ = nullptr;
    }
};
} // namespace Media
} // namespace OHOS
#endif //CameraDemo_avcodec_callback_napi_H
